﻿// ******************************************************
// SMS.Framework
// SMS.Framework.Core
// Calculate.cs
// Copyright (c) 2009, SMS Framework. All Rights Reserved.
// ******************************************************

using System;

namespace SMS.Framework.Core
{

    /// <summary>
    /// Class to do general calculus with dates, etc.
    /// </summary>
    public class Calculate
    {

        #region CONSTUCTORS
            /// <summary>
            /// Constructor of the class.
            /// </summary>
            public Calculate()
            {
            }
        #endregion

        #region FUNCTIONS

            /// <summary> 
            /// Function to know if a year is leap or isn't. 
            /// </summary> 
            /// <param name="year">Year to calculate if a year is leap or isn't.</param> 
            /// <returns>Returns a flag that indicates with true if a year is leap, and false if it isn't.</returns> 
            /// <remarks></remarks> 
            public static bool LeapYear(int year)
            {
                bool response = false;
                if (((year % 4) == 0) & ((year % 100) != 0 | (year % 400) == 0))
                {
                    // The year is leap 
                    response = true;
                }
                return response;
            }

            /// <summary> 
            /// Function to calculate the Eastern Julian Christian date. 
            /// </summary> 
            /// <param name="year">Year to calculate the Eastern Julian Christian date.</param> 
            /// <returns>Returns the date calculated.</returns> 
            /// <remarks></remarks> 
            public static System.DateTime EasterJulianDate(int year)
            {
                int valueOne = year % 4;
                int valueTwo = year % 7;
                int valueThree = year % 19;
                int valueFour = (19 * valueThree + 15) % 30;
                int valueFive = (2 * valueOne + 4 * valueTwo - valueFour + 34) % 7;
                int valueDay = ((valueFour + valueFive + 114) % 31) + 1;
                int valueMonth = (valueFour + valueFive + 114) / 31;
                return new DateTime(year, valueMonth, valueDay);
            }
            // EasterJulianDate 

            /// <summary> 
            /// Function to calculate the Orthodox Christian Easter date. 
            /// </summary> 
            /// <param name="year">Year to calculate the Orthodox Christian date. The year has to be between 1583 and 2299.</param> 
            /// <returns>Returns the date calculated.</returns> 
            /// <remarks></remarks> 
            public static System.DateTime OrthodoxChristianEaster(int year)
            {
                string valueDay = null;
                string valueMonth = null;
                int valueOne = (year % 19);
                int valueTwo = (((19 * valueOne) + 24) % 30);
                int valueThree = (2 * (year % 4));
                int valueFour = (4 * (year % 7));
                int valueFive = (((((6 * valueTwo) + 5) + valueThree) + valueFour) % 7);
                int valueSix = ((valueFive + valueTwo) + 22);
                if ((valueSix > 31))
                {
                    valueSix = (valueSix - 31);
                    if ((valueSix == 26))
                    {
                        valueSix = 19;
                    }
                    valueMonth = "/04/";
                    valueDay = valueSix.ToString();
                }
                else
                {
                    valueMonth = "/03/";
                    valueDay = valueSix.ToString();
                }
                return new DateTime(year, Convert.ToInt32(valueMonth), Convert.ToInt32(valueDay));
            }
            // OrthodoxChristianEaster 

            /// <summary> 
            /// Function to calculate the Catholic Christian Easter date. 
            /// </summary> 
            /// <param name="year">Year to calculate the Catholic Christian Easter date. The year has to be between 1583 and 2299. In some places is said Western Christian.</param> 
            /// <returns>Returns the date calculated.</returns> 
            /// <remarks></remarks> 
            public static System.DateTime CatholicChristianEaster(int year)
            {
                // Algorithm derived by the German mathematician Gauss. 
                // This algorithm calculates the number of days after March 21 (Julian Date). 
                // It's a simpler calculation than the Western Easter. 
                int valueOne = year % 19;
                int valueTwo = year % 4;
                int valueThree = year % 7;
                byte yearStep = Convert.ToByte((year - 2000) / 100);
                int temporalValueOne = 19 * valueOne + (yearStep + 12);
                int valueFour = temporalValueOne % 30;
                int temporalValueTwo = 2 * valueTwo + 4 * valueThree + 6 * valueFour;
                int valueFive = temporalValueTwo % 7;
                int temporalValue = valueFour + valueFive;
                DateTime result = new DateTime(year, 4, 3);
                // Returns the value 
                return result.AddDays(temporalValue);
            }
        // CatholicChristianEaster 

        #endregion
        
    } // Calculate

} // SMS.Framework.Core